#include "chatserver.hpp"
#include "json.hpp"
#include "chatservice.hpp"

#include <functional>//绑定函数的头文件
#include <string>

using namespace std;
using namespace placeholders;//参数占位符
using json = nlohmann::json;

//初始化聊天器服务对象
ChatServer::ChatServer(EventLoop *loop,
                       const InetAddress &listenAddr,
                       const string &nameArg)
    : _server(loop, listenAddr, nameArg), _loop(loop)
{
    //注册链接回调
    _server.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1));
    //注册消息回调
    _server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));
    //设置线程数量
    _server.setThreadNum(4);
}

//启动服务
void ChatServer::start()
{
    _server.start();
}

//上报链接相关的回调函数
void ChatServer::onConnection(const TcpConnectionPtr& conn)
{
    //客户端断开连接
    if(!conn->connected())
    {
        ChatService::instance()->clientCloseException(conn);
        conn->shutdown();//如果连接不成功需要释放socket资源
    }
}
//上报读写事件相关信息的回调函数
void ChatServer::onMessage(const TcpConnectionPtr &conn,
                           Buffer *buffer,
                           Timestamp time)
{
    string buf = buffer->retrieveAllAsString();//把muduo网络库读取到缓冲区的数据放到一个字符串里面
    //数据的反序列化
    json js = json::parse(buf);
    //通过js["msgid"]，绑定回调操作，一个id一个操作，通过js["msgid"]获取业务处理器handler，
    //然后回调handler,把接收到的数据 conn js time传过来
    //达到的目的：完全解耦网络模块的代码和业务模块的代码
    auto msgHandler = ChatService::instance()->getHandler(js["msgid"].get<int>());
    //回调消息绑定好的事件处理器，来执行相应的业务处理
    msgHandler(conn,js,time);
}